// Mod by Jason
// I2C only
// Text only
// ATmega - non arduino

/*********************************************************************
This is a library for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

These displays use SPI to communicate, 4 or 5 pins are required to  
interface

Adafruit invests time and resources providing this open source code, 
please support Adafruit and open-source hardware by purchasing 
products from Adafruit!

Written by Limor Fried/Ladyada  for Adafruit Industries.  
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

//#if ARDUINO >= 100
 //#include "Arduino.h"
//#else
 //#include "WProgram.h"
//#endif
//
//#include <Adafruit_GFX.h>
//


#define FONT_TYPE 3

#define SSD1306_I2C_ADDRESS   0x3C	// 011110+SA0+RW - 0x3C or 0x3D
// Address for 128x32 is 0x3C
// Address for 128x32 is 0x3D (default) or 0x3C (if SA0 is grounded)

/*=========================================================================
    SSD1306 Displays
    -----------------------------------------------------------------------
    The driver is used in multiple displays (128x64, 128x32, etc.).
    Select the appropriate display below to create an appropriately
    sized framebuffer, etc.

    SSD1306_128_64  128x64 pixel display

    SSD1306_128_32  128x32 pixel display

    -----------------------------------------------------------------------*/
   #define SSD1306_128_64
//   #define SSD1306_128_32
/*=========================================================================*/

#if defined SSD1306_128_64 && defined SSD1306_128_32
  #error "Only one SSD1306 display can be specified at once in SSD1306.h"
#endif
#if !defined SSD1306_128_64 && !defined SSD1306_128_32
  #error "At least one SSD1306 display must be specified in SSD1306.h"
#endif

#if defined SSD1306_128_64
  #define SSD1306_LCDWIDTH                  128
  #define SSD1306_LCDHEIGHT                 64
#endif
#if defined SSD1306_128_32
  #define SSD1306_LCDWIDTH                  128
  #define SSD1306_LCDHEIGHT                 32
#endif

#define SSD1306_SETCONTRAST 0x81
#define SSD1306_DISPLAYALLON_RESUME 0xA4
#define SSD1306_DISPLAYALLON 0xA5
#define SSD1306_NORMALDISPLAY 0xA6
#define SSD1306_INVERTDISPLAY 0xA7
#define SSD1306_DISPLAYOFF 0xAE
#define SSD1306_DISPLAYON 0xAF

#define SSD1306_SETDISPLAYOFFSET 0xD3
#define SSD1306_SETCOMPINS 0xDA

#define SSD1306_SETVCOMDETECT 0xDB

#define SSD1306_SETDISPLAYCLOCKDIV 0xD5
#define SSD1306_SETPRECHARGE 0xD9

#define SSD1306_SETMULTIPLEX 0xA8

#define SSD1306_SETLOWCOLUMN 0x00
#define SSD1306_SETHIGHCOLUMN 0x10

#define SSD1306_SETSTARTLINE 0x40
#define SSD1306_SETSTARTPAGE 0XB0 //added

#define SSD1306_MEMORYMODE 0x20
//
//#define SSD1306_COLUMNADDR 0x21
//#define SSD1306_PAGEADDR   0x22
//
#define SSD1306_COMSCANINC 0xC0
#define SSD1306_COMSCANDEC 0xC8

#define SSD1306_SEGREMAP 0xA0

#define SSD1306_CHARGEPUMP 0x8D

#define SSD1306_EXTERNALVCC 0x1
#define SSD1306_SWITCHCAPVCC 0x2

class SSD1306_I2C_Text : public Print {
  public:
  SSD1306_I2C_Text(int8_t RST);
  //SSD1306ASCII(int8_t data, int8_t clk, int8_t dc, int8_t rst, int8_t cs)
  //:data_(data), clk_(clk), dc_(dc), rst_(rst), cs_(cs) {}
//
  //SSD1306ASCII(int8_t data, int8_t clk, int8_t dc, int8_t rst)
  //:data_(data), clk_(clk), dc_(dc), rst_(rst), cs_(-1) {}
  //
  static void charBitmap(uint8_t c, uint8_t* bits);
  void clear();
  uint8_t col() {return col_;}
  void home() {setCursor(0, 0);}
  uint8_t row() {return row_;}
  void setCursor(uint8_t col, uint8_t row);
  void ssd1306_command(uint8_t c);
  void ssd1306_data(uint8_t c);
  void ssd1306_init(uint8_t switchvcc);
  //#if ARDUINO >= 100
  //size_t write(uint8_t c);
  size_t write(const char* s);
  //#else  // ARDUINO >= 100
  //void write(uint8_t c);
  //void write(const char* s);
  //#endif  // ARDUINO >= 100
  private:
  // cursor position
  int8_t col_, row_;
  // OLED pins
  int8_t data_, clk_, dc_, rst_, cs_;
  
  void spiwrite(uint8_t c);
};

//// Scrolling #defines
//#define SSD1306_ACTIVATE_SCROLL 0x2F
//#define SSD1306_DEACTIVATE_SCROLL 0x2E
//#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
//#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
//#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
//#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
//#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
//
//class Adafruit_SSD1306 : public Adafruit_GFX {
 //public:
  ////Adafruit_SSD1306(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS);
  //Adafruit_SSD1306(int8_t RST);
//
  //void begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC, uint8_t i2caddr = SSD1306_I2C_ADDRESS);
  //void ssd1306_command(uint8_t c);
  //void ssd1306_data(uint8_t c);
//
  //void clearDisplay(void);
  ////void invertDisplay(uint8_t i);
  //void display();
//
  ////void startscrollright(uint8_t start, uint8_t stop);
  ////void startscrollleft(uint8_t start, uint8_t stop);
//
  ////void startscrolldiagright(uint8_t start, uint8_t stop);
  ////void startscrolldiagleft(uint8_t start, uint8_t stop);
  ////void stopscroll(void);
//
  ////void drawPixel(int16_t x, int16_t y, uint16_t color);
//
 //private:
  //int8_t _i2caddr, sid, sclk, dc, rst, cs;
  //void fastSPIwrite(uint8_t c);
  //void slowSPIwrite(uint8_t c);
//
  //volatile uint8_t *mosiport, *clkport, *csport, *dcport;
  //uint8_t mosipinmask, clkpinmask, cspinmask, dcpinmask;
//};
//